/**
 *
 */
var crypto=require("crypto"),
    config= require('./config'),
    xmlparse = require('xml2js').parseString;

var request = require('request');

global.wechat = global.wechat || {};

function WeixinHelper(){
}

WeixinHelper.prototype.decrypt = function (strMess,straes){
    var alg = 'des-ede-cbc';
    var cryptkey=new Buffer(straes+"=", 'base64');
    var iv = new Buffer(16);
    cryptkey.copy(iv, 0, 0, 16);
    var encrypted = new Buffer(strMess, 'base64');
    var decipher = crypto.createDecipheriv('aes-256-cbc', cryptkey, iv);
    decipher.setAutoPadding(false);
    decoded  = decipher.update(encrypted, 'base64', 'utf8');
    decoded += decipher.final( 'utf8' );
    return decoded;
};

WeixinHelper.prototype.decryptMessage = function(strMess,corpid,straes){
    var decoded =this.decrypt(strMess,straes);
    //var strlen=decoded.substr(16,4);
    //var buf = new Buffer("strlen");console.log(buf.readUInt32BE(0));
    var  __end=decoded.lastIndexOf(corpid);
    return decoded.substring(20,__end);
}

WeixinHelper.prototype.encrypt = function(strMess,corpid,straes){
    var alg = 'des-ede-cbc';
    var cryptkey=new Buffer(straes+"=", 'base64');
    var iv = new Buffer(16);
    cryptkey.copy(iv, 0, 0, 16);
    var encrypted = new Buffer(strMess, 'utf8');
    decipher = crypto.createCipheriv('aes-256-cbc', cryptkey, iv);
    decoded  = decipher.update(encrypted, 'utf8', 'base64');
    decoded += decipher.final('base64');
    return decoded;
};

function gen(count) {
    var out = "";
    for (var i=0; i<count; i++) {
        out += (((1+Math.random())*0x10000)|0).toString(16).substring(1);
    }
    return out;
}

function AES_encrypt(Input,corpid,straes)
{
    var  xBuff = null;
    var len=Input.length + 32 - Input.length % 32;
    var msg = new Buffer(len);
    Input.copy(msg,0,0,Input.length);

    var pad = KCS7Encoder(Input.length);
    pad.copy(msg,Input.length,0,pad.length);

    var alg = 'des-ede-cbc';
    var cryptkey=new Buffer(straes+"=", 'base64');
    var iv = new Buffer(16);
    cryptkey.copy(iv, 0, 0, 16);//HostToNetworkOrder
    decipher = crypto.createCipheriv('aes-256-cbc', cryptkey, iv);
    decipher.setAutoPadding(false);
    decoded  = decipher.update(msg, 'utf8', 'base64');
    decoded += decipher.final('base64');
    return decoded;
}

WeixinHelper.prototype.encryptMessage = function(strMess,corpid,straes){
    var Randcode = gen(4);
    var bRand = new Buffer(Randcode, 'utf8');
    var  bCorpid =new Buffer(corpid, 'utf8');
    var btmpMsg = new Buffer(strMess, 'utf8');
    var bMsgLen =HostToNetworkOrder(btmpMsg.length);
    var bMsg = new Buffer(bRand.length + bMsgLen.length + bCorpid.length + btmpMsg.length);
    bRand.copy(bMsg,0,0,bRand.length);
    bMsgLen.copy(bMsg,bRand.length,0,bMsgLen.length);
    btmpMsg.copy(bMsg,bRand.length+bMsgLen.length,0,btmpMsg.length);
    bCorpid.copy(bMsg,bRand.length+bMsgLen.length+btmpMsg.length,0,bMsgLen.length);
    return AES_encrypt(bMsg,corpid,straes);

}


WeixinHelper.prototype.getSignatur = function(timestamp,nonce,token,echostr){
    var array=new Array();
    array[0]=token;
    array[1]=timestamp;
    array[2]=nonce;
    array[3]=echostr;
    array.sort();
    var hasher=crypto.createHash("sha1");
    var msg=array[0]+array[1]+array[2]+array[3];
    hasher.update(msg);
    return hasher.digest('hex');
};

WeixinHelper.prototype.isLegel = function isLegel(signature,timestamp,nonce,token,echostr){
    return signature=this.getSignatur(timestamp,nonce,token,echostr);
};


var toLowerCase = function(str) {
    return str.toLowerCase();
};
WeixinHelper.prototype.xmlToJson = function(_body,errback,callback){
    xmlparse(_body, {trim: true,async:false, ignoreAttrs:true,explicitArray:false,tagNameProcessors:[toLowerCase]}, function(err, result) {
        if (err) return errback(err);
        callback(result["xml"]);
    });
};

/**
 * KCS7,补位
 *
 * @param a 需要转化的数字
 * @return 转化得到的字符
 */
function KCS7Encoder(text_length){
    var  block_size = 32;
    // 计算需要填充的位数
    var  amount_to_pad = block_size - (text_length % block_size); //console.log(amount_to_pad);
    if (amount_to_pad == 0)
    {
        amount_to_pad = block_size;
    }
    // 获得补位所用的字符
    var pad_chr = chr(amount_to_pad);
    var tmp = "";
    for (var index = 0; index < amount_to_pad; index++)
    {
        tmp += pad_chr;
    }
    return  new Buffer(tmp, 'utf8');
}

/**
 * 将数字转化成ASCII码对应的字符，用于对明文进行补码
 *
 * @param a 需要转化的数字
 * @return 转化得到的字符
 */
function chr(a){
    return String.fromCharCode(a);
}

function HostToNetworkOrder(inval){
    var outval = 0;
    for (var i = 0; i < 4; i++)
        outval = (outval << 8) + ((inval >> (i * 8)) & 255);
    var buf = new Buffer(4);
    buf.writeInt32LE(outval, 0);
    return buf;
}

WeixinHelper.prototype.getAccessToken = function(callback){
    var tokenObj = global.wechat.tokenObj;
    if(tokenObj && (new Date().getTime()) < tokenObj.expireTime){
        callback(null,tokenObj);
    }
    var url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + config.corpid +"&corpsecret="+config.Secret;
    request(url, function (error, response, body) {
        if(error){
            callback(error);
        }
        if (!error && response.statusCode == 200) {
            tokenObj = JSON.parse(body);
            tokenObj.expireTime = new Date().getTime() + tokenObj.expires_in;
            callback(null,tokenObj);
        }
    });
};


WeixinHelper.prototype.getUserInfo = function(code,callback){
    this.getAccessToken(function(error,result){
        var accessToken = result.access_token;
        var url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token="+ accessToken +"&code="+code+"&agentid="+config.AgentID;
        request(url, function (error, response, body) {
            if(error){
                callback(error);
            }
            if (!error && response.statusCode == 200) {
                var UserId = JSON.parse(body).UserId;
                callback(null,UserId);
            }
        });
    });
};


var helper = new WeixinHelper();
helper.getAccessToken(function(error,result){
    console.log(JSON.stringify(result));
});
module.exports = helper;